import gc

import cv2
import time
import threading
import requests
import logging
# import RPi.GPIO as GPIO
import os
import time
from pathlib import Path

from DectionData import DetectionData
from MyTrackerB import MyTracker

lock = threading.Lock()


# 18
class VideoCapture:

    def __init__(self, config, detector):
        self.config = config
        self.detector = detector
        self.myTrackerList = []
        self.ptCurrentXList = []
        # self.runFlagTimes = 30
        # --------------------------------------------------
        # 创建一个log,用当日的日期写入日志文件
        self.logger = logging.getLogger()
        self.logger.setLevel(logging.INFO)
        logfileName = time.strftime("%Y%m%d", time.localtime())
        logfileName = logfileName + "_log.txt"
        fh = logging.FileHandler(logfileName, mode='w')
        fh.setFormatter(logging.Formatter("[%(asctime)s]:%(levelname)s:%(message)s"))
        self.logger.addHandler(fh)
        # --------------------------------------------------
        # 启动触发器
        # self.setup()

        # -------------------- 消息队列------------------------------
        self.MsgList = []
        # -------------------- 检测队列------------------------------
        # self.AiSrc = []
        # 定义检测线程和发送消息线程
        # self.AIThread = threading.Thread(target=self.AIThreadRun)  # 新建发送消息的线程
        self.sendMsgThread = threading.Thread(target=self.sendMsg2Server)  # 新建发送消息的线程
        # 定义所有的保存路径
        self.indexJpg = 0
        timestr = time.strftime("%Y%m%d", time.localtime())
        self.dirStr = "./img/" + timestr + "/"
        my_path = Path(self.dirStr)
        if not my_path.exists():
            os.makedirs(self.dirStr)
        self.backup_ID = MyTracker.trackerID - 1

    # def setup(self):
    #     GPIO.setmode(GPIO.BCM)
    #     GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    #     GPIO.add_event_detect(17, GPIO.BOTH, callback=self.detect)
    #
    # def detect(self, chn):
    #     global lock
    #     x = GPIO.input(17)
    #     if x == 0:  # 没有东西
    #         pass
    #     if x == 1:  # 有东西
    #         lock.acquire()
    #         self.runFlagTimes = 25
    #         lock.release()

    def addCurrentPointX(self, x1, y1, x2, y2):
        if len(self.ptCurrentXList) == 0:
            self.ptCurrentXList.append([x1, y1, x2, y2])
            return
        for xTemp in self.ptCurrentXList:
            # area = Tools.IntersectionArea(xTemp[0], xTemp[1], xTemp[2], xTemp[3],
            #                               x1, y1, x2, y2)
            x1_avg = (xTemp[0] + xTemp[2]) / 2
            y1_avg = (xTemp[1] + xTemp[3]) / 2
            x2_avg = (x1 + x2) / 2
            y2_avg = (y1 + y2) / 2
            if abs(x1_avg - x2_avg) > self.config.distanceInSamePic or \
                    abs(y1_avg - y2_avg) > self.config.distanceInSamePic:
                self.ptCurrentXList.append([x1, y1, x2, y2])

    def annotate_objects(self, image, results, input_width, input_height):
        currentDetectionList = []
        self.ptCurrentXList.clear()
        # 根据方向的不同，需要花不同的分界线
        if self.config.direct == 1:
            # 18的界限
            cv2.line(image, (MyTracker.min_widthX, 0), (MyTracker.min_widthX, 200), (0, 0, 255), 2)
            cv2.line(image, (MyTracker.max_widthX - self.config.widthStep, 0),
                     (MyTracker.max_widthX - self.config.widthStep, 200), (0, 0, 255), 2)

        else:
            # 19的界限
            cv2.line(image, (MyTracker.min_widthX + self.config.widthStep, 0),
                     (MyTracker.min_widthX + self.config.widthStep, 200), (0, 0, 255), 2)
            cv2.line(image, (MyTracker.max_widthX, 0), (MyTracker.max_widthX, 200), (0, 0, 255), 2)

        for obj in results:
            ymin, xmin, ymax, xmax = obj['bounding_box']
            xmin = int(xmin * input_width)
            xmax = int(xmax * input_width)
            ymin = int(ymin * input_height)
            ymax = int(ymax * input_height)
            h = ymax - ymin
            w = xmax - xmin

            cx = (xmax + xmin) / 2
            # 区别18 和  19
            if self.config.direct == 1:
                # 18 为1
                if MyTracker.min_widthX < cx < MyTracker.max_widthX - self.config.widthStep:
                    cv2.rectangle(image, (xmin, ymin),
                                  (xmax, ymax), (255, 255, 0), 1)
                    # 根据方向，取得不同的h和w,在ini文件种配置
                    if self.config.rect_min_h < h < self.config.rect_max_h \
                            and self.config.rect_min_w < w < self.config.rect_max_w \
                            and w / h < 2.1:
                        self.addCurrentPointX(xmin, ymin, xmax, ymax)

            else:
                # 19 为0
                if MyTracker.min_widthX + self.config.widthStep < cx < MyTracker.max_widthX:
                    cv2.rectangle(image, (xmin, ymin),
                                  (xmax, ymax), (255, 0, 0), 1)
                    # 根据方向，取得不同的h和w,在ini文件种配置
                    if self.config.rect_min_h < h < self.config.rect_max_h \
                            and self.config.rect_min_w < w < self.config.rect_max_w \
                            and w / h < 2.1:
                        self.addCurrentPointX(xmin, ymin, xmax, ymax)

        for k in self.ptCurrentXList:
            current_detection = DetectionData(k[0], k[1], k[2], k[3])
            currentDetectionList.append(current_detection)

        tracklist = MyTracker.trackID(currentDetectionList)

        for i in tracklist:
            print("currentID={0}".format(i.currentID))
            if i.currentID == -1 or i.currentID == -2:
                continue
            # 存档文件，文件中没有显示框
            if self.config.saveFile == 1:
                strjpg = self.dirStr + "{:0>8d}.jpg"
                strjpg = strjpg.format(self.indexJpg)
                cv2.imwrite(strjpg, image)
                self.indexJpg += 1

            cv2.rectangle(image, (i.x1, i.y1),
                          (i.x2, i.y2), (0, 0, 255), 1)
            cv2.putText(image, str(i.currentID),
                        (i.x1, i.y1 - 1), cv2.FONT_HERSHEY_SIMPLEX, 1,
                        [0, 0, 255], 2)

        return image

    def video_capture_func(self):
        global lock
        cap1 = cv2.VideoCapture(0)
        # 启动检测线程和发送消息线程
        self.sendMsgThread.start()
        # self.AIThread.start()
        while True:
            try:
                # 记录每张照片拍照花费时间
                takePicStartTime = time.time() * 1000

                ret, frame_read = cap1.read()
                if not ret:
                    # 视频捕获异常  errorUrl?videoID=
                    url = self.config.errorUrl + "?videoID=" + str(self.config.videoAID)
                    self.logger.info("视频捕获error")
                    self.MsgList.append(url)
                    continue
                self.AIRun(frame_read)

                takePicEndTime = time.time() * 1000
                timeMsg = "all time={0}".format(takePicEndTime - takePicStartTime)

                self.logger.info(timeMsg)
            except Exception as e:
                if len(str(e)) != 0 and str(e).isspace() is not True:
                    errorMsg = "video_capture_func error={0}".format(e)
                    self.logger.info(errorMsg)

    def sendMsg2Server(self):
        while True:
            try:
                if len(self.MsgList) > 0:
                    # 设置秒数超时，仅对于连接有效
                    Response = requests.get(self.MsgList[0], timeout=self.config.timeout)
                    self.logger.info("url={0}".format(self.MsgList[0]))
                    if Response.status_code != 200:
                        self.logger.info("服务器链接异常")
                    else:
                        # 得到服务器的回应
                        # print(Response.content)
                        del self.MsgList[0]
                else:
                    # sleep 1 seconds
                    time.sleep(1)
            except Exception as e:
                if len(str(e)) != 0 and str(e).isspace() is not True:
                    errorMsg = "sendMsg2Server error={0}".format(e)
                    self.logger.info(errorMsg)

    def AIRun(self, frame_read_t):

        # 修改了发送msg线程程序

        try:

            frame_read = frame_read_t[self.config.cut_top:self.config.cut_bottom,
                         self.config.cut_left:self.config.cut_right]

            frame_read_320 = cv2.resize(frame_read,
                                        (320,
                                         320),
                                        interpolation=cv2.INTER_LINEAR)
            frame_read_320_rgb = cv2.cvtColor(frame_read_320, cv2.COLOR_BGR2RGB)
            frame_read_320_rgb = frame_read_320_rgb / 128 - 1
            results = self.detector.detect_objects(frame_read_320_rgb)
            h = self.config.cut_bottom - self.config.cut_top
            w = self.config.cut_right - self.config.cut_left
            imgResult = self.annotate_objects(frame_read, results, w, h)
            if self.config.showVideo == 1:
                cv2.imshow("BBBB", imgResult)
                cv2.waitKey(1)
            if self.backup_ID != (MyTracker.trackerID - 1):
                self.logger.info("sum={0}".format(MyTracker.trackerID - 1))
                self.backup_ID = MyTracker.trackerID - 1
                url = self.config.sumUrl + "?videoID=" + str(self.config.videoAID) + "&rectID=1"
                self.MsgList.append(url)

        except Exception as e:
            if len(str(e)) != 0 and str(e).isspace() is not True:
                errorMsg = "AIThreadRun error={0}".format(e)
                self.logger.info(errorMsg)
